package cppcloud

import "encoding/binary"

const (
	VERSION     = 1
	HEADLEN     = 10
	MAXBODY_LEN = 1024 * 1024
)

// ToBytes  转化为发送的字节数组
func ToBytes(cmdid uint16, seqid uint16, body []byte) (ret []byte) {
	totalLen := HEADLEN + len(body)
	i := 0

	ret = make([]byte, totalLen)
	ret[i] = VERSION
	i++
	ret[i] = HEADLEN
	i++

	putUint32(ret, &i, uint32(len(body)))
	putUint16(ret, &i, cmdid)
	putUint16(ret, &i, seqid)

	for j := 0; i < totalLen; i++ {
		ret[i] = body[j]
		j++
	}

	return ret
}

type MsgError struct {
	emsg string
}

// 统计信息
type MsgStat struct {
	SendBytes int64
	RecvBytes int64
	SendPkgn  int64
	RecvPkgn  int64
}

func (e *MsgError) Error() (ret string) {
	return e.emsg
}

// ParseHead  接收数组流转化成消息头
func ParseHead(bs []byte) (cmdid uint16, seqid uint16, bodyLen uint32, err error) {
	cmdid = 0
	seqid = 0
	bodyLen = 0
	if len(bs) < HEADLEN {
		err = &MsgError{"HeadLen less"}
		return
	}

	i := 0
	version := popUint8(bs, &i)
	headLen := popUint8(bs, &i)

	if version != VERSION || headLen != HEADLEN {
		err = &MsgError{"Version or HeadLen not match"}
		return
	}

	bodyLen = popUint32(bs, &i)
	cmdid = popUint16(bs, &i)
	seqid = popUint16(bs, &i)

	return
}

func putUint8(arr []byte, index *int, val byte) {
	arr[*index] = val
	*index++
}

func putUint16(arr []byte, index *int, val uint16) {
	binary.BigEndian.PutUint16(arr[*index:], val)
	*index += 2
}

func putUint32(arr []byte, index *int, val uint32) {
	binary.BigEndian.PutUint32(arr[*index:], val)
	*index += 4
}

func popUint8(arr []byte, index *int) byte {
	val := arr[*index]
	*index++
	return val
}
func popUint16(arr []byte, index *int) uint16 {
	val := binary.BigEndian.Uint16(arr[*index:])
	*index += 2
	return val
}

func popUint32(arr []byte, index *int) uint32 {
	val := binary.BigEndian.Uint32(arr[*index:])
	*index += 4
	return val
}
